//  NSGAII_main.java
//
//  Author:
//       Antonio J. Nebro <antonio@lcc.uma.es>
//       Juan J. Durillo <durillo@lcc.uma.es>
//
//  Copyright (c) 2011 Antonio J. Nebro, Juan J. Durillo
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
// 
//  You should have received a copy of the GNU Lesser General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

package jmetal.metaheuristics.nsgaII;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.logging.FileHandler;
import java.util.logging.Logger;

import jmetal.core.Algorithm;
import jmetal.core.Operator;
import jmetal.core.Problem;
import jmetal.core.SolutionSet;
import jmetal.operators.crossover.CrossoverFactory;
import jmetal.operators.mutation.MutationFactory;
import jmetal.operators.selection.SelectionFactory;
import jmetal.util.HvIndicator;
import jmetal.util.JMException;
import jmetal.util.MathUtil;

/**
 * Class to configure and execute the NSGA-II algorithm.
 * 
 * Besides the classic NSGA-II, a steady-state version (ssNSGAII) is also
 * included (See: J.J. Durillo, A.J. Nebro, F. Luna and E. Alba "On the Effect
 * of the Steady-State Selection Scheme in Multi-Objective Genetic Algorithms"
 * 5th International Conference, EMO 2009, pp: 183-197. April 2009)
 */

public class NSGAII_WFG_time {
	public static Logger logger_; // Logger object
	public static FileHandler fileHandler_; // FileHandler object

	/**
	 * @param args
	 *            Command line arguments.
	 * @throws JMException
	 * @throws IOException
	 * @throws SecurityException
	 *             Usage: three options -
	 *             jmetal.metaheuristics.nsgaII.NSGAII_main -
	 *             jmetal.metaheuristics.nsgaII.NSGAII_main problemName -
	 *             jmetal.metaheuristics.nsgaII.NSGAII_main problemName
	 *             paretoFrontFile
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void main(String[] args)
			throws JMException, SecurityException, IOException, ClassNotFoundException, NoSuchMethodException,
			InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Problem problem; // The problem to solve
		Algorithm algorithm; // The algorithm to use
		Operator crossover; // Crossover operator
		Operator mutation; // Mutation operator
		Operator selection; // Selection operator

		HashMap parameters; // Operator parameters

		HvIndicator indicators; // Object to get quality indicators

		indicators = null;
		String outDirect = "";

		String[] probName = { "jmetal.problems.WFG.WFG1", "jmetal.problems.WFG.WFG2", "jmetal.problems.WFG.WFG3",
				"jmetal.problems.WFG.WFG4", "jmetal.problems.WFG.WFG5", "jmetal.problems.WFG.WFG6",
				"jmetal.problems.WFG.WFG7", "jmetal.problems.WFG.WFG8","jmetal.problems.WFG.WFG9"};

		Integer[] popuSize = { 0, 0, 0, 120, 0, 210, 0, 0, 156, 0, 276 };// 种群数量
//		Integer[] varSize = { 4, 9, 9, 9, 9, 9, 19 };  
		Integer[] dimension = { 3,  5,  8,10 };//目标数
		
		outDirect = "results/temp/FitnessNsga/";
		String path = outDirect+"time_WFG.dat";
		FileOutputStream output = new FileOutputStream(new File(path));
		for (int dimNum = 3; dimNum < dimension.length; dimNum++) {
			for (int probNum = 0; probNum < probName.length; probNum++) {
				Class<?> dtlz = Class.forName(probName[probNum]);
				Constructor<?> constr = dtlz.getConstructor(String.class, Integer.class, Integer.class,Integer.class);
				problem = (Problem) constr.newInstance("Real", 2*(dimension[dimNum]-1), 20,dimension[dimNum]);

				indicators = new HvIndicator(problem);
				algorithm = new FitnessNsga(problem);
//				algorithm = new AngleDIR(problem);
//				algorithm = new NSGAII(problem);

				// Algorithm parameters
				algorithm.setInputParameter("populationSize", popuSize[problem.getNumberOfObjectives()]);
				algorithm.setInputParameter("maxEvaluations", popuSize[problem.getNumberOfObjectives()] * 1001);

				// Mutation and Crossover for Real codification
				parameters = new HashMap();
				parameters.put("probability", 1.0);
				parameters.put("distributionIndex", 30.0);
				crossover = CrossoverFactory.getCrossoverOperator("SBXCrossover", parameters);

				parameters = new HashMap();
				parameters.put("probability", 1.0 / problem.getNumberOfVariables());
				parameters.put("distributionIndex", 20.0);
				mutation = MutationFactory.getMutationOperator("PolynomialMutation", parameters);

				// Selection Operator
				parameters = null;
				selection = SelectionFactory.getSelectionOperator("BinaryTournamentDirFitness", parameters);

				// Add the operators to the algorithm
				algorithm.addOperator("crossover", crossover);
				algorithm.addOperator("mutation", mutation);
				algorithm.addOperator("selection", selection);

				// Add the indicator object to the algorithm
				algorithm.setInputParameter("indicators", indicators);
				
				int run = 1;
				for (int i = 0; i < run; i++) {
					System.out.println(problem.getName()+"_"+problem.getNumberOfObjectives()+"D_RUN_"+i);
					// Execute the Algorithm
					long initTime = System.currentTimeMillis();
					SolutionSet population = algorithm.execute();
					long estimatedTime = System.currentTimeMillis() - initTime;

					// Result messages
					System.out.println("Total execution time: " + estimatedTime + "ms");
					String time = problem.getName()+"_"+problem.getNumberOfObjectives()+"D:\t"+estimatedTime+"\n";
					System.out.println(time);
					output.write(time.getBytes());
				}
				
				
				
			}
		}
		output.close();
	} // main
}
